/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "Rnd.h"
#include <algorithm>
#include <limits>
#include <threads/threads.h>

#ifdef WIN_VERSION
#include <windows.h>
#endif

static int start = 0;

namespace liba
{

static int process_current(int current)
{
	return (current >> 16) & 0x7fff;
}

void Rnd::random_seed()
{
#ifndef WIN_VERSION
	unsigned long long microsec = threads::get_precise_tick_count();
	current = start + microsec;
	start += 1;
#else
	current = start + GetTickCount();
	start += 1;
#endif
}


Rnd::Rnd()
{
	random_seed();
}

Rnd::Rnd(unsigned start)
:	current( start )
{}

Rnd::Rnd(const Rnd & other)
{
	random_seed();
}
	
Rnd & Rnd::operator= (const Rnd & other)
{
	random_seed();
	return *this;
}

int Rnd::get_random(int min, int max)
{
	current = find_next( current );
	if( min > max )
		std::swap( min, max );
	return min + process_current(current) % (1 + max - min);
}

int Rnd::get_random(int range)
{
	current = find_next( current );
	return process_current(current) % range;
}

double Rnd::get_random()
{
	current = find_next( current );
	int mask = 0x7fff;//std::numeric_limits<int>::max();
	return double(process_current(current) & mask)/mask;
}

unsigned Rnd::find_next(unsigned num)
{
	return num = num * 214013 + 2531011;
//	return num = num * 1103515245 + 12345; // by Strous
}

} // namespace liba
